package com.galaxy.payment.service.impl;

import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.galaxy.common.core.exception.ServiceException;
import com.galaxy.payment.api.RemoteOrderService;
import com.galaxy.payment.api.RemoteUserService;
import com.galaxy.payment.domain.OrderBo;
import com.galaxy.payment.domain.bo.AccountFlowBo;
import com.galaxy.payment.domain.bo.PaymentBo;
import com.galaxy.payment.domain.vo.PaymentRecordVo;
import com.galaxy.payment.service.IAccountFlowService;
import com.galaxy.payment.service.IAliPayService;
import com.galaxy.payment.service.IPaymentRecordService;
import com.galaxy.payment.utils.AliPayUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 支付宝支付服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AliPayServiceImpl implements IAliPayService {

    private final AliPayUtils aliPayUtils;
    private final IPaymentRecordService paymentRecordService;

    @Autowired
    private RemoteOrderService remoteOrderService;

    @Autowired
    private IAccountFlowService iAccountFlowService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createPay(String orderNo, String amount, String subject,Long userId,Long orderId) {
        try {
            log.info("开始创建支付宝支付，订单号：{}，金额：{}，商品名称：{}", orderNo, amount, subject);
            PaymentRecordVo paymentRecord = paymentRecordService.getPaymentRecordByOrderNo(orderNo);
            // 1. 创建支付记录
            if(paymentRecord == null){
                PaymentBo bo = new PaymentBo();
                bo.setOrderNo(orderNo);
                bo.setPaymentAmount(new java.math.BigDecimal(amount));
                bo.setPaymentType(4); // 支付宝支付
                bo.setUserId(userId);
                bo.setOrderId(orderId);
                paymentRecord = paymentRecordService.createPayment(bo);
                if (paymentRecord == null) {
                    throw new ServiceException("创建支付记录失败");
                }
            }


            // 2. 调用支付宝支付接口
            String payHtml = aliPayUtils.createPay(
                paymentRecord.getPayNo(),
                subject,
                paymentRecord.getPaymentAmount()
            );

            // 3. 更新支付记录
            PaymentBo updateBo = new PaymentBo();
            updateBo.setPayNo(paymentRecord.getPayNo());
            updateBo.setStatus(1); // 支付中
            updateBo.setPayTime(new Date());
            updateBo.setId(paymentRecord.getId());
            updateBo.setExpireTime(new Date(System.currentTimeMillis() + 30 * 60 * 1000)); // 30分钟过期
            paymentRecordService.updateByBo(updateBo);

            log.info("创建支付宝支付成功，订单号：{}", orderNo);
            return payHtml;
        } catch (Exception e) {
            log.error("创建支付宝支付失败，订单号：{}", orderNo, e);
            throw new ServiceException("创建支付宝支付失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String queryPayStatus(String orderNo, String type) {
        try {
            log.info("开始查询支付宝支付状态，订单号：{}", orderNo);

            // 1. 查询支付记录
            PaymentRecordVo paymentRecord = paymentRecordService.getPaymentRecordByOrderNo(orderNo);
            if (paymentRecord == null) {
                log.error("支付记录不存在，订单号：{}", orderNo);
                return "NOT_FOUND";
            }

            // 2. 如果已经支付成功，直接返回
            if (paymentRecord.getStatus() == 2) {
                log.info("订单已支付成功，订单号：{}", orderNo);
                return "PAID";
            }

            // 3. 查询支付宝订单状态
            String status = aliPayUtils.queryPayStatus(orderNo);
            log.info("支付宝订单状态：{}，订单号：{}", status, orderNo);

            // 4. 更新支付记录状态
            if ("PAID".equals(status)) {
                AccountFlowBo accountFlowBo = new AccountFlowBo();
                accountFlowBo.setUserId(paymentRecord.getUserId());
                accountFlowBo.setOrderNo(paymentRecord.getOrderNo());
                accountFlowBo.setFlowType(Objects.equals(type, "充值") ? 1 : 2);
                accountFlowBo.setAmount(Objects.equals(type, "充值")?paymentRecord.getPaymentAmount():paymentRecord.getPaymentAmount().negate());

                accountFlowBo.setBalance(BigDecimal.ZERO);
                accountFlowBo.setDescription(Objects.equals(type, "充值") ? "充值余额" : "支付宝购买商品");
                iAccountFlowService.insertByBo(accountFlowBo);


                PaymentBo updateBo = new PaymentBo();
                updateBo.setPayNo(paymentRecord.getPayNo());
                updateBo.setStatus(2); // 支付成功
                updateBo.setSuccessTime(new Date());
                updateBo.setId(paymentRecord.getId());
                paymentRecordService.updateByBo(updateBo);
                OrderBo orderBo =  new OrderBo();
                orderBo.setId(paymentRecord.getOrderId());
                orderBo.setPayType(4);
                orderBo.setStatus(2);
                orderBo.setOutTradeNo(paymentRecord.getPayNo());
                orderBo.setPayTime(LocalDateTime.now());
                remoteOrderService.edit(orderBo);

            }

            return status;
        } catch (Exception e) {
            log.error("查询支付宝支付状态失败，订单号：{}", orderNo, e);
            return "ERROR";
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String generatePayQrCode(String orderNo, String amount, String subject,Long userId,Long orderId,String type) {
        try {
            log.info("开始生成支付宝支付二维码，订单号：{}，金额：{}，商品名称：{}", orderNo, amount, subject);

            // 1. 创建支付记录
            PaymentRecordVo paymentRecord = paymentRecordService.getPaymentRecordByOrderNo(orderNo);
            if(paymentRecord != null && paymentRecord.getStatus() == 2){
                return "ORDER_ALREADY_PAID";
            }
            // 1. 创建支付记录
            if(paymentRecord == null){
                PaymentBo bo = new PaymentBo();
                bo.setOrderNo(orderNo);
                bo.setPaymentAmount(new java.math.BigDecimal(amount));
                bo.setPaymentType(4); // 支付宝支付
                bo.setUserId(userId);
                bo.setOrderId(orderId);
                paymentRecord = paymentRecordService.createPayment(bo);
                if (paymentRecord == null) {
                    throw new ServiceException("创建支付记录失败");
                }
            }

            // 2. 生成支付二维码
            String qrCode = aliPayUtils.generateBase64QrCode(
                paymentRecord.getOrderNo(),
                amount,
                subject,
                 type
            );

            // 3. 更新支付记录
            PaymentBo updateBo = new PaymentBo();
            updateBo.setPayNo(paymentRecord.getPayNo());
            updateBo.setStatus(1); // 支付中
            updateBo.setPayTime(new Date());
            updateBo.setId(paymentRecord.getId());
            updateBo.setExpireTime(new Date(System.currentTimeMillis() + 30 * 60 * 1000)); // 30分钟过期
            paymentRecordService.updateByBo(updateBo);

            log.info("生成支付宝支付二维码成功，订单号：{}", orderNo);
            return qrCode;
        } catch (Exception e) {
            log.error("生成支付宝支付二维码失败，订单号：{}", orderNo, e);
            throw new ServiceException("生成支付宝支付二维码失败：" + e.getMessage());
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean closePay(String payNo) {
        try {
            log.info("开始关闭支付宝支付订单，支付单号：{}", payNo);

            // 1. 查询支付记录
            PaymentRecordVo paymentRecord = paymentRecordService.getPaymentRecord(payNo);
            if (paymentRecord == null) {
                throw new ServiceException("支付记录不存在");
            }

            // 2. 如果支付已完成，不能关闭
            if (paymentRecord.getStatus() == 2) {
                throw new ServiceException("支付已完成，不能关闭");
            }

            // 3. 调用支付宝关单接口
            aliPayUtils.closePay(payNo);

            // 4. 更新支付状态
            PaymentBo updateBo = new PaymentBo();
            updateBo.setPayNo(payNo);
            updateBo.setStatus(4); // 已关闭
            return paymentRecordService.updateByBo(updateBo);
        } catch (Exception e) {
            log.error("关闭支付宝支付订单失败，支付单号：{}", payNo, e);
            throw new ServiceException("关闭支付宝支付订单失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean refund(String payNo, String reason) {
        try {
            log.info("开始申请支付宝退款，支付单号：{}，原因：{}", payNo, reason);

            // 1. 查询支付记录
            PaymentRecordVo paymentRecord = paymentRecordService.getPaymentRecord(payNo);
            if (paymentRecord == null) {
                throw new ServiceException("支付记录不存在");
            }

            // 2. 如果支付未完成，不能退款
            if (paymentRecord.getStatus() != 2) {
                throw new ServiceException("支付未完成，不能退款");
            }

            // 3. 调用支付宝退款接口
            AlipayTradeRefundResponse response = aliPayUtils.refund(
                payNo,
                paymentRecord.getPaymentAmount(),
                reason
            );

            // 4. 更新支付状态
            PaymentBo updateBo = new PaymentBo();
            updateBo.setPayNo(payNo);
            updateBo.setStatus(5); // 已退款
            return paymentRecordService.updateByBo(updateBo);
        } catch (Exception e) {
            log.error("申请支付宝退款失败，支付单号：{}", payNo, e);
            throw new ServiceException("申请支付宝退款失败：" + e.getMessage());
        }
    }
}
